﻿using ExcellentProjectPlus.Dominio.Examenes.Entidades;
using ExcellentProjectPlus.Dominio.Examenes.Repositorios;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExcellentProjectPlus.Dominio.Examenes.Servicios.Calendarizaciones
{
    public class ServicioDeAdministracionDeCalendarizacion
       : IServicioDeAdministracionDeCalendarizacion
    {
        #region Atributos
        IUnidadDeTrabajoExamenes _unidadDeTrabajo;
        #endregion

        #region Constructores
        public ServicioDeAdministracionDeCalendarizacion(IUnidadDeTrabajoExamenes unidadDeTrabajo)
        {
            _unidadDeTrabajo = unidadDeTrabajo;
        }
        #endregion

        public IEnumerable<Calendarizacion> ObtenerCalendarizaciones()
        {
            return _unidadDeTrabajo.RepositorioCalendarizacion.Obtener();
        }
        public Calendarizacion ObtenerCalendarizacionPorId(int id)
        {
            return _unidadDeTrabajo.RepositorioCalendarizacion.ObtenerPorId(id);
        }
        public void AgregarCalendarizacion(Calendarizacion calendarizacion)
        {

            #region Validacion Fechas para crear un nuevo Exámen Calendarizado
            if (calendarizacion.Fecha < calendarizacion.Fecha || calendarizacion.Fecha >= calendarizacion.FechaCierre)
                throw new ArgumentOutOfRangeException("FechaInicio", "La fecha de inicio debe estar dentro del rango"
                    + calendarizacion.Fecha + " - " + calendarizacion.FechaCierre);

            if (calendarizacion.FechaCierre > calendarizacion.FechaCierre || calendarizacion.FechaCierre <= calendarizacion.Fecha)
                throw new ArgumentOutOfRangeException("FechaFin", "La fecha de fin debe estar dentro del rango "
                    + calendarizacion.Fecha + " - " + calendarizacion.FechaCierre);
            #endregion

            _unidadDeTrabajo.RepositorioCalendarizacion.Agregar(calendarizacion);
            _unidadDeTrabajo.Confirmar();
        }
        public void ModificarCalendarizacion(Calendarizacion calendarizacion)
        {
            _unidadDeTrabajo.RepositorioCalendarizacion.Modificar(calendarizacion);
            _unidadDeTrabajo.Confirmar();
        }
        public void EliminarCalendarizacion(Calendarizacion calendarizacion)
        {
            _unidadDeTrabajo.RepositorioCalendarizacion.Eliminar(calendarizacion);
            _unidadDeTrabajo.Confirmar();
        }

        public IEnumerable<Calendarizacion> ObtenerCalendarizacionesPaginado(int pagina, int tamanio)
        {
            return _unidadDeTrabajo.RepositorioCalendarizacion.Obtener(orderBy: c => c.OrderBy(calend => calend.IdCalendarizacion),
                page: pagina, pageSize: tamanio);
        }

        public IEnumerable<Calendarizacion> ObtenerFechasCalendarizacion(DateTime fechaseleccionada)
        {
            var dayNumber = (int)fechaseleccionada.DayOfWeek;
            var fecha = new DateTime(fechaseleccionada.Year, fechaseleccionada.Month, fechaseleccionada.Day);
            var fechaInicio = fecha.AddDays((double)(-1) * dayNumber);
            var fechaFin = fecha.AddDays(6 - dayNumber);

            return _unidadDeTrabajo.RepositorioCalendarizacion.Obtener(c =>
                c.Fecha >= fechaInicio && c.Fecha <= fechaFin).ToList();
        }

        public IEnumerable<InformacionCalendarizacionExamen> ObtenerInformacionCalendarizacionExamen(string estado)
        {
            if (string.IsNullOrWhiteSpace(estado))
            {
                return _unidadDeTrabajo.RepositorioCalendarizacion.ObtenerInformacionCalendarizacionExamen();
            }
            else
            {
                return _unidadDeTrabajo.RepositorioCalendarizacion.ObtenerInformacionCalendarizacionExamen(c => c.Estado.Equals(estado, StringComparison.OrdinalIgnoreCase));
            }
        }

        public IEnumerable<Calendarizacion> ObtenerExamenesPendientesPorCurso(int idCurso)
        {
            return _unidadDeTrabajo.RepositorioCalendarizacion.Obtener(c => c.IdCurso == idCurso &&
                            c.FechaCierre > DateTime.Now && c.Estado == "Activo", cal => cal.OrderBy(c1 => c1.Fecha)).ToList();
        }


        public IEnumerable<Calendarizacion> ObtenerExamenesPendientesPorEstudiante(int idCurso, int idEstudiante)
        {
            return _unidadDeTrabajo.RepositorioCalendarizacion.ObtenerExamenesPorEstudiante(idCurso, idEstudiante);
        }
    }
}
